/**
 * 
 */
package lt.inkredibl.iit;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.Action;
import javax.swing.JProgressBar;

public class TransformTask
	implements Runnable
{
	private Tetragon _q;
	private ImgComponent _ic;
	private int _width;
	private int _height;
	private JProgressBar _pb;
	private Action _a;

	public TransformTask(ImgComponent ic, JProgressBar pb, Action a)
	{
		_ic = ic;
		_pb = pb;
		_a = a;
	}

	public void setDimensions(int width, int height)
	{
		_width = width;
		_height = height;
	}

	public void setTetragon(Tetragon q)
	{
		_q = q;
	}

	public void run()
	{
		TetragonIterable ti = new TetragonIterable(_q, _width, _height);
		Rectangle2D bounds = _q.bounds();

		bounds.add(Math.floor(bounds.getX()), Math.floor(bounds.getY()));
		bounds.add(Math.ceil(bounds.getX() + bounds.getWidth()), Math
			.ceil(bounds.getY() + bounds.getHeight()));
		
		// TODO implement run-time resulting image display
		BufferedImage img = new BufferedImage(_width, _height,
			BufferedImage.TYPE_3BYTE_BGR);
		Graphics g = img.getGraphics();

		int pixels = 0;
		_pb.setMaximum(_width * _height);
		_pb.setValue(0);
		_pb.setVisible(true);

		Matrix<Point2D> m = ti.split();
		ArrayList<Point2D> poly = new ArrayList<Point2D>(4);
		for (int i = 1; i < m.getWidth(); i++)
		{
			for (int j = 1; j < m.getHeight(); j++)
			{
				_pb.setValue(++pixels);
				poly.clear();
				poly.add(m.get(i-1, j-1));
				poly.add(m.get(i, j-1));
				poly.add(m.get(i, j));
				poly.add(m.get(i-1, j));
				g.setColor(calcPixel(poly));
				g.fillRect(i-1, j-1, 1, 1);
			}
		}

		_pb.setVisible(false);

		try
		{
			ImageIO.write(img, "png", new File("out.png"));
		}
		catch (IOException e3)
		{
			e3.printStackTrace();
		}

		// for (int i = 0; i < 4; i++)
		// {
		// //_ic.addDrawable(DrawableEdge.valueOf(q.getEdge(i).split(_width)));
		// _ic.addDrawable(DrawableEdge.valueOf(q.getEdge(i).split(_width).stretch(new
		// Point2D.Double(0, 0), new Point2D.Double(255, 255))));
		// }

		_a.setEnabled(true);
		_ic.clearDrawables();
		_ic.repaint();
	}

	private Color calcPixel(ArrayList<Point2D> poly)
	{
		double red = 0;
		double green = 0;
		double blue = 0;
		double totalAmount = 0;
		Rectangle2D.Double bounds = new Rectangle2D.Double(poly.get(0).getX(),
			poly.get(0).getY(), 0, 0);
		for (Point2D pt : poly)
		{
			bounds.add(pt);
		}

		bounds.add(Math.floor(bounds.getX()), Math.floor(bounds.getY()));
		bounds.add(Math.ceil(bounds.getX() + bounds.getWidth()), Math
			.ceil(bounds.getY() + bounds.getHeight()));

		Pixel p = Pixel.inst(0, 0);
		
		int bx = (int) bounds.getX();
		int by = (int) bounds.getY();
		for (int x = 0; x < bounds.getWidth(); x++)
		{
			for (int y = 0; y < bounds.getHeight(); y++)
			{
				p.setLocation(bx + x, by + y);
				double amount = p.amount(poly);
				Color color = _ic.getImagePixel(p.getX(), p.getY());
				red += color.getRed() * amount;
				green += color.getGreen() * amount;
				blue += color.getBlue() * amount;
				totalAmount += amount;
			}
		}

		return new Color((int) (red / totalAmount),
			(int) (green / totalAmount), (int) (blue / totalAmount));
	}

	public static TransformTask inst(ImgComponent ic, JProgressBar pb, Action a)
	{
		return new TransformTask(ic, pb, a);
	}
}